<template>
  <div class="custom-select-tree">
    <el-select
      ref="elSelect"
      v-model="selectedList"
      :popper-class="popperClass"
      :clearable="clearable"
      :disabled="disabled"
      :placeholder="placeholder"
      :style="styles"
      :filterable="filterable"
      :multiple="multiple"
      :collapse-tags="collapseTags"
      @remove-tag="handleRemoveTag"
      @clear="clear"
      @change="handelSelectChange"
    >
      <el-option v-if="treeList && treeList.length > 0" :value="inputVal">
        <el-scrollbar style="height:100%">
          <el-tree
            ref="elTree"
            node-key="code"
            style="maxHeight:245px"
            :data="treeList"
            :indent="indent"
            :highlight-current="true"
            :default-expand-all="true"
            :expand-on-click-node="false"
            check-strictly
            :props="defaultProps"
            :show-checkbox="showCheckbox"
            :render-content="renderContent"
            @check-change="handleCheckChange"
          >
            <div class="custom-tree-node" slot-scope="{node, data}">
              <span class="node-label">{{ node.label }}</span>
              <el-button
                v-if="data.id !== '0'"
                type="text"
                class="node-btn"
                :class="{
                  'check-node': node.data.isCurrentAndLowerLevel
                }"
                size="mini"
                @click="() => handleSelected(node, data)"
              >
                本级及下级
              </el-button>
            </div>
          </el-tree>
        </el-scrollbar>
      </el-option>
    </el-select>
  </div>
</template>
<script>
import utils from '@/hotent-ui-util.js'
export default {
  name: 'CustomSelectTree',
  props: {
    popperClass: {
      type: String,
      default: 'custom-tree__select'
    },
    styles: {
      type: Object,
      default() {
        return {}
      }
    },
    clearable: {
      type: Boolean,
      default: true
    },
    filterable: {
      type: Boolean,
      default: false
    },
    indent: {
      type: Number,
      default: 8
    },
    showCheckbox: {
      type: Boolean,
      default: false
    },
    multiple: {
      type: Boolean,
      default: false
    },
    collapseTags: {
      type: Boolean,
      default: false
    },
    renderContent: Function,
    treeData: Array,
    placeholder: {
      type: String,
      default: '请选择'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    selectedOrg: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      treeList: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      valueDesc: '',
      selectedList: [],
      childrenData: [],
      treeDataCopy: []
    }
  },
  computed: {
    inputVal: {
      get: function() {
        if (!this.value) {
          return ''
        }
        return this.value
      },
      set: function(val) {
        this.$emit('input', val)
      }
    }
  },
  watch: {
    treeData:{
      handler(val){
        if (val&&val.length) {
        const cloneTreeList = _.cloneDeep(val)
        if (this.selectedOrg && this.selectedOrg.length) {
          const codeList = this.selectedOrg.map(item => item.code)
          const selectedObj = this.selectedOrg.reduce((pre, cur) => {
            pre[cur.code] = cur.isCurrentAndLowerLevel
            return pre
          }, {})
          const flatTreeList = utils.nest2tile(cloneTreeList)
          const list = flatTreeList.map(it => {
            if(codeList.includes(it.code)){
              this.selectedList.push(it.name)
            }
            return {
              ...it,
              isCurrentAndLowerLevel: selectedObj[it.code]
                ? selectedObj[it.code]
                : it.isCurrentAndLowerLevel
            }
          })
          const filterList = _.cloneDeep(list)
          //获取选择本级及下级的组织ID
          const orgIds = filterList
            .filter(item => item.isCurrentAndLowerLevel)
            .map(item => item.id)
          const newList = filterList.filter(
            item => !orgIds.includes(item.parentId)
          )
          const data = _.cloneDeep(utils.tile2nest(newList))
          if (data.length > 1) {
            this.treeList = [data[0]]
          } else {
            this.treeList = data
          }
          this.$nextTick(() => {
            if(this.$refs.elTree){
              this.$refs.elTree.setCheckedKeys(codeList)
            }
          })
        } else {
          this.treeList = cloneTreeList
        }
      }
      },
      immediate:true
    },
    selectedList: {
      handler(val) {
        if (val.length < 1) {
          this.$refs.elTree.setCheckedKeys([])
        }
      },
      deep: true
    }
  },
  mounted() {
    this.treeDataCopy = this.treeData
  },
  methods: {
    clear() {
      this.changeIsCurrentAndLowerLevel(this.treeList)
      this.$refs.elTree.setCheckedKeys([])
    },
    changeIsCurrentAndLowerLevel(data) {
      data.forEach(item => {
        if (item.isCurrentAndLowerLevel) {
          item.isCurrentAndLowerLevel = false
        }
        if (item.children && item.children.length) {
          this.changeIsCurrentAndLowerLevel(item.children)
        }
      })
    },
    //设置当前节点是否选择本级及下级
    setCurrentNodeIsNext(data,name){
      const treeList = _.cloneDeep(data)
      treeList.forEach(item=>{
        if(item.name === name){
          item.isCurrentAndLowerLevel = false
        }
        if(item.children && item.children.length){
          this.setCurrentNodeIsNext(item.children,name)
        }
      })
      this.treeList = [...treeList]
    },
    handleRemoveTag(tag) {
      this.setCurrentNodeIsNext(this.treeData,tag)
    },
    handelSelectChange(val){
      const checkedNodeList = this.$refs.elTree.getCheckedNodes()
      const selectedKey = checkedNodeList
        .filter(item =>{
         return  val.includes(item.name)
        })
        .map(it => it.code)
      this.$refs.elTree.setCheckedKeys(selectedKey)
    },
    handleSelected(node, data) {
      if (!node.data.isCurrentAndLowerLevel) {
        const checkedNodeList = this.$refs.elTree.getCheckedNodes()
        const checkedKeys = checkedNodeList.map(item => item.code)
        this.$refs.elTree.setCheckedKeys(
          new Set([...checkedKeys, node.data.code])
        )
        if (node.childNodes && node.childNodes.length) {
          this.$set(data, 'children', [])
        }
      } else {
        this.findCurrentChildren(this.treeData, data.code)
        if (this.childrenData && this.childrenData.length) {
          this.$set(data, 'children', this.childrenData)
        }
      }
      this.$set(
        node.data,
        'isCurrentAndLowerLevel',
        !node.data.isCurrentAndLowerLevel
      )
    },
    findCurrentChildren(treeData, code) {
      const data = _.cloneDeep(treeData)
      if (!data) return
      for (let i = 0; i < data.length; i++) {
        if (data[i].code === code) {
          this.childrenData = data[i].children
          return
        } else {
          if (data[i].children) {
            this.findCurrentChildren(data[i].children, code)
          }
        }
      }
    },
    handleCheckChange(data, checked) {
      const checkedNodeList = this.$refs.elTree.getCheckedNodes()
      const list = checkedNodeList.filter(item => item.id !== '0')
      this.selectedList = list.map(item => item.name)
      this.$emit('check-change', list)
    }
  }
}
</script>
<style lang="scss" scoped>
div[aria-invalid='true'] {
  ::v-deep {
    .el-input__inner,
    .el-input__inner:focus {
      border-color: #f56c6c;
    }
  }
}

.custom-select-tree {
  ::v-deep {
    .el-select {
      width: 100%;
    }
  }
}

.el-select-dropdown__item.hover,
.el-select-dropdown__item:hover {
  padding-right: 0;
  padding-left: 0;
  background-color: #fff;
}

.el-select-dropdown__item {
  font-size: 14px;
  padding: 0 20px;
  position: relative;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: #606266;
  height: 100%;
  line-height: 34px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  cursor: pointer;
}

li.el-select-dropdown__item.selected {
  font-weight: normal;
  padding-right: 0;
  padding-left: 0;
}
</style>
